home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / std / c / 373 < prev    next >
Internet Message Format  |  1996-08-06  |  5KB

  1. Path: cs.tu-berlin.de!jutta
  2. From: jutta@cs.tu-berlin.de (Jutta Degener)
  3. Newsgroups: comp.std.c
  4. Subject: Re: setjmp usage question
  5. Date: 25 Feb 1996 12:24:24 GMT
  6. Organization: Technical University of Berlin, Germany
  7. Message-ID: <4gpkdo$jm8@news.cs.tu-berlin.de>
  8. References: <4gnusq$7be@senator-bedfellow.MIT.EDU>
  9. NNTP-Posting-Host: kugelbus.cs.tu-berlin.de
  10. Mime-Version: 1.0
  11. Content-Type: text/plain; charset=iso-8859-1
  12. Content-Transfer-Encoding: 8bit
  13.  
  14. tada@athena.mit.edu (Michael J Zehr) writes:
  15. > I'm trying to determine whether a particular usage of setjmp is
  16. > sanctioned by the standard and I'm finding a compiler bug or whether my
  17. > usage is non-conforming.
  18.  
  19. Your usage is non-conforming.  The reason for that is not important
  20. to what you're asking, but I'll mention it to get it out of the way.
  21. The standard has restricted the ways in which setjmp() can be used:
  22.  
  23. #         An invocation of the "setjmp" macro shall appear only in one of
  24. # the following contexts:
  25. #       * The entire controlling expression of a selection of iteration
  26. #         statement;
  27. #       * one operand of a relational or equality operator with the
  28. #         other operand an integral constant expression, with the resulting
  29. #         expression being the entire controlling expression of a selection
  30. #         or iteration statement;
  31. #       * the operand of a unary ! operator with the resulting expression
  32. #         being the entire controlling expression of a selection or iteration
  33. #         statement; or
  34. #       * the entire expression of an expression statement (possibly cast
  35. #         to void).
  36. #                        --- ANSI Section 4.6.1.1
  37.  
  38. Your statement, 
  39.  
  40. >    if (*error_code = setjmp(env[env_index++])) {
  41.  
  42. is neither of these cases (the '=' means assignment, not equality), so the
  43. program's behavior is undefined.
  44.  
  45. Let's imagine you had written
  46.  
  47.     if (setjmp(env[env_index++])) {
  48.  
  49. > Should this code work correctly?  In particular, can a compiler
  50. > increment env_index after longjmp is called?
  51.  
  52. I think the code might or might not work, and the compiler is free to
  53. increment env_index after longjmp is called and flow control has returned
  54. to the setjmp statement.  The standard doesn't impose any ordering on
  55. the act of "returning" from the longjmp invocation and on the side
  56. effects from the setjmp() statement---macro invocations like setjmp()
  57. do not imply sequence points in the way function invocations do.
  58.  
  59. > [Additional question because I'm curious:  what happens to
  60. > post-increments that are in parameters of the longjmp call?
  61.  
  62. I think that unless you take special care, the same applies, but you'll
  63. find people to argue otherwise.  (See below.)
  64.  
  65. For a bit of background---
  66.  
  67. The standard specifies one type of sequence point that's interesting
  68. for us here: 
  69.  
  70. #       The order of evaluation of the function designator, the arguments,
  71. #  and subexpressions within the arguments is unspecified, but there is a
  72. #  sequence point before the actual call.
  73. #
  74. #                --ANSI section 3.3.2.2, Function Calls.
  75.  
  76. That this is the only place that applies is in itself significant: there
  77. are no special sequence points for longjmp and setjmp; they behave just
  78. like any old function---or macro.
  79.  
  80. Setjmp, although it looks much like a function, is not described as a
  81. function in the standard; it is a macro.  Among other things, that means
  82. you can't rely on a sequence point between the evaluation of setjmp's
  83. argument and the "call".
  84.  
  85. Longjmp is described as a function in the standard.  Does that mean it
  86. is a function?  Yes and no.  There is a function called longjmp, and if
  87. you write a call
  88.  
  89.     #include <setjmp.h>
  90.     (longjmp)(env[env_index++], 1);
  91. or
  92.     #include <setjmp.h>
  93.     #undef longjmp
  94.     longjmp(env[env_index++], 1);
  95. or
  96.     #include <setjmp.h>
  97.     void (* f)(jmp_buf, int) = longjmp;
  98.     f(env[env_index++], 1);
  99.  
  100. so that longjmp can't possibly be a macro, you are guaranteed to get
  101. a real function, complete with sequence point and all.  In these cases,
  102.  
  103.     (longjmp)(env[env_index++], 1);
  104.  
  105. is equivalent to
  106.  
  107.     env_index++; longjmp(env[env_index - 1], 1);
  108.  
  109. since the side effects of the "++" operator must be complete before
  110. the actual function is invoked.
  111.  
  112. But as long as you don't jump through any of the three hoops above
  113. and naively use
  114.  
  115.     #include <setjmp.h>
  116.     longjmp(env[env_index++], 1);
  117.  
  118. what you actually get may or may not be a call to the "real" longjmp
  119. function, because 
  120.  
  121. #     Any function declared in a header may be additionally
  122. #   implemented as a macro
  123. #
  124. #        -- ANSI Section 4.1.6, Use of Library Functions
  125.  
  126. Whether this means that
  127.  
  128. (a) users cannot rely on the sequence point between argument evaluation
  129.     and call unless they make sure they're using a "real" function
  130.  
  131. or whether this means that
  132.  
  133. (b) implementors who implement Standard C functions as macros must
  134.     guarantee that function-call like sequence points apply even in 
  135.     the macro expansions
  136.  
  137. hasn't been formally decided within WG14 yet, as far as I remember.
  138.  
  139. Jutta Degener (jutta@cs.tu-berlin.de), speaking only for myself.
  140.